package com.z.system.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.z.system.dto.UserDTO;
import com.z.system.dto.UserRequestDTO;
import com.z.system.model.User;
import com.z.system.service.UserService;
import com.z.system.utils.PageResult;
import com.z.system.utils.R;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 用户管理控制器
 */
@RestController
@RequestMapping("/api/user")
@Tag(name = "用户管理", description = "用户相关接口")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/current")
    @Operation(summary = "获取当前登录用户信息", description = "返回当前登录用户的基本信息", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(content = @Content(schema = @Schema(implementation = UserDTO.class))))
    public R<UserDTO> getCurrentUser() {
        User user = userService.getCurrentUser();
        Set<UUID> roleIds = userService.getUserRoleIds(user.getId());
        UserDTO userDTO = new UserDTO(user, roleIds);
        return R.success("请求成功", userDTO);
    }

    /**
     * 获取当前登录用户的详细信息
     * 返回格式与前端fetchGetUserInfo函数要求匹配
     */
    @GetMapping("/info")
    @Operation(summary = "获取当前登录用户详细信息", description = "返回当前登录用户的详细信息，包括权限信息")
    public R<Map<String, Object>> getUserInfo() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            User user = (User) principal;
            // 构建返回结果
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("username", user.getUsername());
            userInfo.put("userSn", user.getUserSn());
            userInfo.put("userId", user.getId());
            userInfo.put("email", user.getEmail());

            // 从User对象中获取权限信息
            List<String> roles = new ArrayList<>();
            for (GrantedAuthority authority : user.getAuthorities()) {
                roles.add(authority.getAuthority());
            }
            userInfo.put("roles", roles);

            return R.success("请求成功", userInfo);
        }
        return R.error(401, "未认证");
    }

    /**
     * 获取用户列表
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:user:view')")
    @Operation(summary = "获取用户列表", description = "分页查询用户列表，支持条件筛选", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(content = @Content(schema = @Schema(implementation = PageResult.class))))
    public R<PageResult<UserDTO>> getUsers(
            @Parameter(description = "页码，从0开始", required = true, example = "0") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页条数", required = true, example = "10") @RequestParam(defaultValue = "10") int size,
            @Parameter(description = "用户名") @RequestParam(required = false) String username,
            @Parameter(description = "工号") @RequestParam(required = false) String userSn,
            @Parameter(description = "邮箱") @RequestParam(required = false) String email,
            @Parameter(description = "部门ID") @RequestParam(required = false) UUID deptId,
            @Parameter(description = "启用状态(0禁用，1启用)") @RequestParam(required = false) Integer enable) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createTime").descending());
        Map<String, Object> params = new HashMap<>();
        params.put("username", username);
        params.put("userSn", userSn);
        params.put("email", email);
        params.put("deptId", deptId);
        params.put("enable", enable);

        Page<UserDTO> userPage = userService.getUsers(pageable, params);

        // 使用通用分页实体封装结果
        PageResult<UserDTO> result = new PageResult<>(
                userPage.getContent(),
                userPage.getNumber() + 1,
                userPage.getSize(),
                userPage.getTotalElements());

        return R.success("请求成功", result);
    }

    /**
     * 获取用户详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:user:view')")
    @Operation(summary = "获取用户详情", description = "根据ID获取用户详细信息", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(content = @Content(schema = @Schema(implementation = UserDTO.class))))
    public R<UserDTO> getUser(@Parameter(description = "用户ID", required = true) @PathVariable UUID id) {
        User user = userService.getUserById(id);
        if (user == null) {
            return R.error(404, "用户不存在");
        }
        // 转换为UserDTO
        Set<UUID> roleIds = userService.getUserRoleIds(user.getId());
        UserDTO userDTO = new UserDTO(user, roleIds);
        return R.success("请求成功", userDTO);
    }

    /**
     * 创建用户
     */
    @PostMapping("/add")
    @PreAuthorize("hasAuthority('sys:user:create')")
    @Operation(summary = "创建用户", description = "新增用户信息", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = UserRequestDTO.class))), responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(content = @Content(schema = @Schema(implementation = UserDTO.class))))
    public R<String> createUser(
            @Parameter(description = "用户信息", required = true) @RequestBody UserRequestDTO userRequestDTO) {
        // 转换DTO为实体
        User user = userRequestDTO.toUser();
        userService.saveUser(user);

        return R.success("创建成功", "");
    }

    /**
     * 更新用户
     */
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @Operation(summary = "更新用户", description = "修改用户信息", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = UserRequestDTO.class))), responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(content = @Content(schema = @Schema(implementation = UserDTO.class))))
    public R<String> updateUser(
            @Parameter(description = "用户信息", required = true) @RequestBody UserRequestDTO userRequestDTO) {
        // 转换DTO为实体
        User user = userRequestDTO.toUser();
        userService.updateUser(user);
        return R.success("更新成功", "");
    }

    /**
     * 删除用户
     */
    @PostMapping("/delete/{id}")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @Operation(summary = "删除用户", description = "根据ID删除用户")
    public R<String> deleteUser(@Parameter(description = "用户ID", required = true) @PathVariable UUID id) {
        userService.deleteUser(id);
        return R.success("删除成功", id.toString());
    }

    /**
     * 批量删除用户
     */
    @PostMapping("/delete/batch")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @Operation(summary = "批量删除用户", description = "批量删除多个用户")
    public R<String> deleteUsers(@Parameter(description = "用户ID集合", required = true) @RequestBody Set<UUID> ids) {
        userService.deleteUsers(ids);
        return R.success("删除成功", "");
    }

    /**
     * 更新用户状态
     */
    @PutMapping("/{id}/status")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @Operation(summary = "更新用户状态", description = "启用或禁用用户")
    public R<String> updateUserStatus(
            @Parameter(description = "用户ID", required = true) @PathVariable UUID id,
            @Parameter(description = "状态值(0禁用，1启用)", required = true) @RequestParam Integer enable) {
        userService.updateUserStatus(id, enable);
        return R.success("更新成功", "");
    }

    /**
     * 重置用户密码
     */
    @PutMapping("/{id}/reset-password")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @Operation(summary = "重置用户密码", description = "管理员重置用户密码")
    public R<String> resetPassword(
            @Parameter(description = "用户ID", required = true) @PathVariable UUID id,
            @Parameter(description = "新密码", required = true) @RequestParam String password) {
        userService.resetPassword(id, password);
        return R.success("重置成功", "");
    }

    /**
     * 修改用户密码
     */
    @PutMapping("/change-password")
    @Operation(summary = "修改用户密码", description = "用户修改自己的密码")
    public R<String> changePassword(
            @Parameter(description = "旧密码", required = true) @RequestParam String oldPassword,
            @Parameter(description = "新密码", required = true) @RequestParam String newPassword) {
        userService.changePassword(oldPassword, newPassword);
        return R.success("修改成功", "");
    }

    /**
     * 分配用户角色
     */
    @PutMapping("/{id}/roles")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @Operation(summary = "分配用户角色", description = "为用户分配角色权限")
    public R<String> assignRoles(
            @Parameter(description = "用户ID", required = true) @PathVariable UUID id,
            @Parameter(description = "角色ID集合", required = true) @RequestBody Set<UUID> roleIds) {
        userService.assignRoles(id, roleIds);
        return R.success("分配成功", "");
    }

    /**
     * 获取用户角色ID集合
     */
    @GetMapping("/{id}/roles")
    @PreAuthorize("hasAuthority('sys:user:view')")
    @Operation(summary = "获取用户角色ID集合", description = "查询用户已分配的角色ID列表")
    public R<Set<UUID>> getUserRoles(@Parameter(description = "用户ID", required = true) @PathVariable UUID id) {
        return R.success("请求成功", userService.getUserRoleIds(id));
    }
}